package com.xyh.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyh.common.util.ShiroUtil;
import com.xyh.common.util.TreeUtil;
import com.xyh.system.mapper.MenuMapper;
import com.xyh.system.model.Menu;
import com.xyh.system.model.User;
import com.xyh.system.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author kyle
 * @since 2021-01-05
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Autowired
    private MenuMapper menuMapper;

    /**
     * 获取当前登陆用户拥有的树形菜单 (admin 账户拥有所有权限.)
     */
    @Override
    public List<Menu> selectCurrentUserMenuTree() {
        // 从shiro中取出当前登录用户
        User currentUser = ShiroUtil.getCurrentUser();

        return selectMenuTreeByUsername(currentUser.getUsername());
    }

    /**
     * 根据用户名获取该用户拥有的树形菜单
     *
     * @param username 用户名
     * @return 封装好的树状层级关系的Menu集合
     */
    @Override
    public List<Menu> selectMenuTreeByUsername(String username) {
        List<Menu> menus = null;

        if ("admin".equals(username)) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.orderByAsc("order_num");
            menus = menuMapper.selectList(queryWrapper);
        } else {
            menus = menuMapper.selectMenuByUserName(username);
        }

        return toTree(menus);
    }

    /**
     * 将普通的Menu集合转换为树形结构
     */
    private List<Menu> toTree(List<Menu> menuList) {
        return TreeUtil.toTree(menuList, "menuId", "parentId", "children", Menu.class);
    }

    /**
     * 查询所有的menu，并组装层级关系(数据库直接子查询获取)
     *
     * @return 有树状层级关系的Menu集合
     */
    @Override
    public List<Menu> selectAllTree() {
        return menuMapper.selectAllTree();
    }

    @Override
    public List<Menu> getLeafNodeMenu() {
        List<Menu> menus = selectAllTree();
        return TreeUtil.getAllLeafNode(menus);
    }

    /**
     * 根据父id查询该id的菜单有所有子集菜单
     *
     * @param parentId 菜单父id
     * @return 父级菜单下的所有子集菜单(不包括子集的子集)
     */
    @Override
    public List<Menu> selectChildMenuByParentId(Integer parentId) {

        return menuMapper.selectChildMenuByParentId(parentId);
    }

    /**
     * 获取全部菜单树，并且手动添加顶层跟目录
     *
     * @return
     */
    @Override
    public List<Menu> getAllMenuTreeAndRoot() {
        List<Menu> menus = menuMapper.selectAllTree();
        return addRootNode("导航目录", 0, menus);
    }

    /**
     * 将树形结构添加到一个根节点下
     *
     * @param rootName
     * @param rootId
     * @param children
     * @return
     */
    public List<Menu> addRootNode(String rootName, Integer rootId, List<Menu> children) {
        Menu root = new Menu();
        root.setMenuName(rootName);
        root.setMenuId(rootId);
        root.setChildren(children);

        List<Menu> rootList = new ArrayList<>();
        rootList.add(root);
        return rootList;
    }

    /**
     * 查询带功能权限的菜单树,并组装根节点
     *
     * @return Menu菜单树集合
     */
    @Override
    public List<Menu> getAllMenuAndCountOperatorTreeAndRoot() {
        List<Menu> menus = menuMapper.selectAllMenuAndCountOperator();
        return addRootNode("导航目录", 0, menus);
    }

    /**
     * 调整菜单排序
     *
     * @param currentId 需要调整的菜单id
     * @param swapId    与之交换的菜单id
     */
    @Override
    public void swapSort(Integer currentId, Integer swapId) {
        menuMapper.swapSort(currentId, swapId);
    }

    /**
     * 新增菜单节点，并且刷新过滤器链
     *
     * @param menu
     * @return
     */
    @Override
    public boolean insert(Menu menu) {
        Integer maxOrderNum = menuMapper.selectMaxOrderNum();
        menu.setOrderNum(maxOrderNum + 1);
        return this.save(menu);
    }

    /**
     * 删除菜单节点，如果存在下级节点则一并删除
     *
     * @param menuId
     * @return
     */
    @Override
    public boolean removeByParentIdEqMenuId(Integer menuId) {

        return menuMapper.removeByParentIdEqMenuId(menuId) > 0;
    }
}
